<template>
  <!-- <div class="home">
    <h1>首页</h1>
    <p>a:{{count}}</p>
    <p>b:{{str}}</p>
    <p>obj:{{obj}}</p>
    <button @click="update">按钮</button>
  </div> -->
  <!-- 测试computed的功能 -->
  <div>
    <input type="text" name="Firstname" v-model="Firstname" />
    <input type="text" name="Lastname" v-model="Lastname" />
    <br />
    Fullname:{{ Fullname }}
    <button @click="updata">修改名字</button>
  </div>
  <div>
    <input type="text" v-model="str" />
  </div>
  <br>
  <div>
    <input type="text" placeholder="我会自动的获取焦点" ref="Focus"/>
  </div>

  <hr>

<h2>展示shallowReactive和shallowRef</h2>

<h3>m1:{{m1}}</h3>
<h3>m2::{{m2}}</h3>

<button @click="update">按钮</button>
<hr>

<div>
  state:{{Rawstate}}
  <button @click="testToRaw">按钮</button>
  <button @click="testMarkRaw">测试markRaw</button>
</div>

<hr>
<p>{{refState}}</p>
<p>{{foo}}</p>
<p>{{foo2}}</p>
<button @click="refUpdate">按钮</button>
</template>

<script lang="ts">
import { computed, defineComponent, markRaw, nextTick, onMounted, reactive, ref, shallowReactive, shallowRef, toRaw,toRef, toRefs, watch, watchEffect } from "vue";

export default defineComponent({
  name: "HomeView",
  // vue2的方法写
  // data(){
  //   return{
  //     a:1,
  //     b:2
  //   }
  // },
  // methods:{
  //     handler(){
  //       console.log("handler1");

  //     }
  // },
  // vue3的方法写
  setup() {
    //   let a=ref(1);
    //   let b=ref(2);

    //   const handler=()=>{
    //     console.log("handler2");
    //     a.value++;
    //     b.value++
    //   }
    // return{
    //   a,
    //   b,
    //   handler
    // }

    // const state = reactive({
    //     count:1,
    //     str:'str',
    //     boo:true,
    //     obj:{a:1}
    // })

    // const update=()=>{
    //     state.count++,
    //     state.str+="--",
    //     state.obj.a++
    // }

    // return{
    //   ...toRefs(state),
    //   update
    // }

    const user = reactive({
      Firstname: "zhang",
      Lastname: "san",
    });

    const str = ref("abc");
    // 监听某个数据的值，第一参数是监听的值，后一个参数是回调函数
    // watch(str, (newvalue, oldvalue) => {
    //   console.log(newvalue, oldvalue);
    // });
    // const Fullname=computed(()=>{
    //   return user.Firstname+'  '+user.Lastname
    // })

    // 监听对象中的数据，需要用一个函数来指定
    // watch(
    //   () => user.Firstname,
    //   (newvalue, oldvalue) => {
    //     console.log(newvalue, oldvalue);
    //   }
    // );

    // 监听多个数据
    watch([str, () => user.Firstname], (newvalue, oldvalue) => {
      console.log(newvalue, oldvalue);
    });

    // const Fullname = computed({
    //   get() {
    //     return user.Firstname + "  " + user.Lastname;
    //   },
    //   set(value: String) {
    //     const names = value.split(" ");
    //     user.Firstname = names[0];
    //     user.Lastname = names[1];
    //   },
    // });

    const Fullname = ref(" ")

    // watch([()=>user.Firstname,()=>user.Lastname],(newvalue,oldvalue)=>{
    //     Fullname.value=newvalue[0]+' '+newvalue[1]
    // },{
    //   immediate:true
    // })

// 使用watchEffect对数据进行立即监听
    watchEffect(()=>{
      Fullname.value=user.Firstname+" "+user.Lastname
    })

    const updata = () => {
      Fullname.value = "Li Si";
    };

    const Focus=ref<HTMLElement | null>(null)
// 通过原始的方式进行获取焦点
    // onMounted(()=>{
    //    Focus.value && Focus.value.focus()
    // })
  
// 通过nextTick将数据进行处理
    nextTick(()=>{
      Focus.value && Focus.value.focus()
    })

// 测试shallowReactive和shallowRef的功能
    const m1=shallowReactive({a:1,b:{c:2}})
    const m2:any=shallowRef({a:1,b:{c:2}})

const update=()=>{
   m1.a+=1  //有效
  //  m1.b.c+=1  无效输出，shallowReactive只能监听第一层数据,如果页面重新渲染，他将会改变（其他数据发生响应的时候）

  // m2.value.a+=1  无效，shallowRef只能在值发生改变时被监听,如果页面重新渲染，他将会改变（其他数据发生响应的时候）
  m2.value ={a:23}
}
// 测试toRaw和markRaw
const Rawstate=reactive<any>({
  name:"tom",
  age:25
})
const testToRaw=()=>{
  const user=toRaw(Rawstate)
  user.age++  //页面不会更新,但还在后台的数据是发生改变了的
  // Rawstate.age++
  console.log(user);//打印后是一个普通的对象
  console.log(Rawstate);//打印后是一个响应式的对象 
}

const testMarkRaw=()=>{
  const likes=['a','b']
  // Rawstate.likes=likes
  Rawstate.likes=markRaw(likes)//likes将不是响应式的代码
  console.log(Rawstate.likes);
  setTimeout(()=>{
        Rawstate.likes.push('c')
  },1000)
  
}
// toRef的使用
const refState =reactive({
  foo:1,
  bar:2
})

const foo = toRef(refState,"foo");//创建一个refState.foo的引用，现在foo和state.foo是引用关系
const foo2 = ref(refState.foo);//拷贝，foo2和refState.foo没关系，只是将他的值拷贝了一份


const refUpdate = ()=>{
  // refState.foo++;
  // foo.value++//他和refState是引用的关系
  foo2.value++//这个值只是foo2的值在边，refState中的foo值并没有改变
}

    return {
      ...toRefs(user),
      Fullname,
      updata,
      str,
      Focus,
      m1,
      m2,
      update,
      Rawstate,
      testToRaw,
      testMarkRaw,
      foo,
      foo2,
      refUpdate,
      refState
    };
  },
});
</script>
